package cppcloud

import (
	"fmt"
	"strconv"
	"strings"
	"time"
)

type statItem struct {
	attr    map[string]int
	svrname string
}

const IntervalSec = 10

type SvrStat struct {
	stats    map[string]*statItem
	cloudapp *CloudApp
	timerRun bool
	exitCh   chan bool
}

func CreateSvrStat(capp *CloudApp) *SvrStat {
	return &SvrStat{
		stats:    make(map[string]*statItem),
		cloudapp: capp,
	}
}

// svrKey的格式：regname + '-' + svrid + '-' + prvdid
func (svst *SvrStat) getStatObj(svrKey string) *statItem {
	if item, ok := svst.stats[svrKey]; ok {
		return item
	}

	keyItm := strings.Split(svrKey, "-")
	if len(keyItm) != 3 {
		fmt.Println("STATOBJ| msg=invalid svrKey", svrKey)
		return nil
	}

	svrid, _ := strconv.Atoi(keyItm[1])
	prvdid, _ := strconv.Atoi(keyItm[2])
	ret := &statItem{
		attr:    map[string]int{},
		svrname: keyItm[0],
	}

	ret.attr["svrid"] = svrid
	if prvdid > 0 {
		ret.attr["prvdid"] = prvdid
	}
	svst.stats[svrKey] = ret
	return ret
}

func (svst *SvrStat) AddPrvdCount(svrKey string, isOk bool, dcount int) {
	item := svst.getStatObj(svrKey)
	if nil == item {
		return
	}

	if isOk {
		item.attr["pvd_ok"] += dcount
	} else {
		item.attr["pvd_ng"] += dcount
	}

	svst._startStatTimer()
}

func (svst *SvrStat) AddInvkCount(svrKey string, isOk bool, dcount int) {
	item := svst.getStatObj(svrKey)
	if nil == item {
		return
	}

	if isOk {
		item.attr["ivk_ok"] += dcount
	} else {
		item.attr["ivk_ng"] += dcount
	}

	svrid, ok := item.attr["svrid"]
	if ok && svrid > 0 && svst.cloudapp.Svrid() != svrid { // 自己调用自己不算
		// 修改被调用者属性
		if isOk {
			item.attr["ivk_dok"] += dcount
		} else {
			item.attr["ivk_dng"] += dcount
		}
	}

	svst._startStatTimer()
}

func (svst *SvrStat) shutdown() {
	svst.exitCh <- true
}

func (svst *SvrStat) _startStatTimer() {
	if !svst.timerRun {
		go svst._sendStat()
	}
}

func (svst *SvrStat) _sendStat() {
	svst.timerRun = true
	defer func() { svst.timerRun = false }()

	select {
	case <-time.After(time.Second * IntervalSec):
	case <-svst.exitCh:
		return
	}

	msg := make([]interface{}, 0)
	for _, value := range svst.stats {
		listItem := make(map[string]interface{})
		listItem["regname"] = value.svrname
		for key2, val2 := range value.attr {
			listItem[key2] = val2
		}

		msg = append(msg, listItem)
		delete(value.attr, "ivk_dok")
		delete(value.attr, "ivk_dng")
	}

	if len(msg) > 0 {
		fmt.Println("Stat msg:", msg)
		svst.cloudapp.RequestNoWait(CMD_SVRSTAT_REQ, msg)
	}
}
